/*
 * SeparatorDelegate.cpp  0.4.0 / Dec 05, 2010
 *
 * Copyright (c) 2010 - 2011, cute4j.com and contributors.
 *
 * This software is licensed under the LGPL version 2.1 license.
 * A copy of this license is included in the file LICENSE-LGPL.txt.
 */
#include "SeparatorDelegate.h"

#include "ToolBarDelegate.h"

// SeparatorData :: Protected Constructor. -------------------------------------

/*!
 * \brief Constructs new SeparatorData object.
 */
SeparatorData::SeparatorData()
  : ActionComponentData(), orientation(Qt::Horizontal)
{
  // empty constructor body
}

// SeparatorDelegate :: Protected Constructor. ---------------------------------

/*!
 * \brief Constructs new SeparatorDelegate object.
 *
 * \param env the JNIEnv pointer
 * \param obj the Separator java object
 */
SeparatorDelegate::SeparatorDelegate(JNIEnv *env, jobject obj)
  : ActionComponentDelegate(env, obj)
{
  // empty constructor body
}

// SeparatorDelegate :: Native Calls. ------------------------------------------

/*!
 * \brief Sets separator orientation.
 *
 * \param env the JNIEnv pointer
 * \param orientation the orientation
 */
void SeparatorDelegate::setOrientation(JNIEnv *env, jint orientation)
{
  Q_ASSERT(env);
  SWING_REENTRANT(setOrientation, SWING_ENV_ARG, JINT_ARG(orientation))
  switch(orientation) {
    case 0:
      if (isQWidget()) {
        separator()->setOrientation(Qt::Horizontal);
      } else {
        separatorActionData()->orientation = Qt::Horizontal;
      }
      break;
    case 1:
      if (isQWidget()) {
        separator()->setOrientation(Qt::Vertical);
      } else {
        separatorActionData()->orientation = Qt::Vertical;
      }
      break;
  }
  jniObject()->callVoidMethod(sm_orientationChangedMID, orientation);
}

/*!
 * \brief Sets separator text.
 *
 * \param env the JNIEnv pointer
 * \param text the text
 */
void SeparatorDelegate::setText(JNIEnv *env, jstring text)
{
  Q_ASSERT(env);
  Q_ASSERT(text);
  SWING_REENTRANT(setText, SWING_ENV_ARG, JSTRING_ARG(text))
  if (isQWidget()) {
    separator()->setText(QStringAdapter(env, text));
  } else {
    action()->setText(QStringAdapter(env, text));
  }
}

// SeparatorDelegate :: Static Native Calls. -----------------------------------

/*!
 * \brief Initializes SeparatorDelegate class.
 *
 * \param env the JNIEnv pointer
 * \param cls the Separator java class
 *
 * \exception FatalError if failed
 */
void SeparatorDelegate::initialize(JNIEnv *env, jclass cls)
{
  Q_ASSERT(env);
  Q_ASSERT(cls);
  Q_ASSERT(!sm_orientationChangedMID);
  if (!INIT_UMID(orientationChanged, cls, "(I)V")) {
    FATAL_LOGGED_ERROR("SeparatorDelegate initialization failed");
  }
}

/*!
 * \brief Returns new instance of the delegate object
 *
 * \param env the JNIEnv pointer
 * \param obj the Swing object
 * 
 * \return new instance of the delegate object
 */
jlong SeparatorDelegate::newInstance(JNIEnv *env, jobject obj)
{
  if (JNISwingWrapper::isSwingThread(env)) {
    return reinterpret_cast<jlong>(new SeparatorDelegate(env, obj));
  }
  return SwingUtilitiesDelegate::invokeLongAndWait(env, obj, createMID());
}

// SeparatorDelegate :: Native Callback. ---------------------------------------

/*!
 * \brief Calls \c orientationChanged method of the separator object.
 *
 * \param orientation the orientation
 */
void SeparatorDelegate::orientationChanged(jint orientation)
{
  jniObject()->callVoidMethod(sm_orientationChangedMID, orientation);
}

// SeparatorDelegate :: Protected Method. --------------------------------------

/*!
 * \brief orientationChanged slot.
 *
 * \param orientation the orientation
 */
void SeparatorDelegate::orientationChangedSlot(Qt::Orientation orientation)
{
  switch(orientation) {
    case Qt::Horizontal:
      orientationChanged(0);
      break;
    case Qt::Vertical:
      orientationChanged(1);
      break;
  }
}

// SeparatorDelegate :: Overridden Member Functions. ---------------------------

/*!
 * \inheritDoc
 */
void SeparatorDelegate::setParentDelegate(ContainerDelegate *parentDelegate)
{
  ContainerDelegate *oldParentDelegate = this->parentDelegate();
  ToolBarDelegate *toolBarDelegate;
  if (oldParentDelegate) {
    toolBarDelegate = qobject_cast<ToolBarDelegate *>(oldParentDelegate);
    if (toolBarDelegate) {
      disconnect(toolBarDelegate->qToolBar(),
                 SIGNAL(orientationChanged(Qt::Orientation)),
                 SLOT(orientationChangedSlot(Qt::Orientation)));
    }
  }
  if (parentDelegate) {
    toolBarDelegate = qobject_cast<ToolBarDelegate *>(parentDelegate);
    if (toolBarDelegate) {
      connectDirect(toolBarDelegate->qToolBar(),
                    SIGNAL(orientationChanged(Qt::Orientation)),
                    SLOT(orientationChangedSlot(Qt::Orientation)));
      orientationChangedSlot(toolBarDelegate->qToolBar()->orientation());
    }
  }
  ActionComponentDelegate::setParentDelegate(parentDelegate);
}

/*!
 * \inheritDoc
 */
void SeparatorDelegate::setForeground(JNIEnv *env, jint argb)
{
  if (isQWidget()) {
    separator()->setUseStylePalette(false);
  }
  ActionComponentDelegate::setForeground(env, argb);
}

/*!
 * \inheritDoc
 */
void SeparatorDelegate::setNullForeground(JNIEnv *env)
{
  if (isQWidget()) {
    separator()->setUseStylePalette(true);
  }
  ActionComponentDelegate::setNullForeground(env);
}

/*!
 * \brief Creates QWidget adaptee.
 *
 * \return QWidget adaptee
 */
QWidget *SeparatorDelegate::createQWidget()
{
  return new QSeparatorAdapter();
}

/*!
 * \brief Creates QAction adaptee.
 *
 * \return QAction adaptee
 */
QAction *SeparatorDelegate::createQAction()
{
  QAction *action = new QAction(this);
  action->setSeparator(true);
  return action;
}

/*!
 * \inheritDoc
 */
QWidget *SeparatorDelegate::convertToQWidget(QAction *action)
{
  QSeparatorAdapter *separator = static_cast<QSeparatorAdapter *>(
                             ActionComponentDelegate::convertToQWidget(action));
  separator->setText(action->text());
  SeparatorData *data = static_cast<SeparatorData *>(getActionData(action));
  if (data) {
    separator->setOrientation(data->orientation);
    separator->setUseStylePalette(!data->foreground.isValid());
  }
  return separator;
}

/*!
 * \inheritDoc
 */
QAction *SeparatorDelegate::convertToQAction(QWidget *widget)
{
  QSeparatorAdapter *separator = static_cast<QSeparatorAdapter *>(widget);
  QAction *action = ActionComponentDelegate::convertToQAction(widget);
  action->setText(separator->text());
  SeparatorData *data = static_cast<SeparatorData *>(getActionData(action));
  data->orientation = separator->orientation();
  return action;
}

/*!
 * \inheritDoc
 */
ActionComponentData *SeparatorDelegate::createActionData()
{
  return new SeparatorData();
}

// SeparatorDelegate :: Private Static Data Member. ----------------------------

jmethodID SeparatorDelegate::sm_orientationChangedMID = 0;
